package services

import (
	"fmt"
	"strings"

	G "enzyme-backend/core/generated"
	"enzyme-backend/core/models"
)

type ProxyTemplate struct {
	proxies []*models.ProxyNode
	rules   []models.RuleConfig
}

var GlobalProxyTemplate *ProxyTemplate

func init() {
	GlobalProxyTemplate = &ProxyTemplate{}
	GlobalProxyTemplate.LoadRules(G.ValidRules)
}

func (pt *ProxyTemplate) LoadRules(rules []models.RuleConfig) error {
	pt.rules = rules
	return nil
}

func (pt *ProxyTemplate) LoadProxies(proxies []*models.ProxyNode) error {
	pt.proxies = proxies
	return nil
}

// generateProxyConfig 生成代理配置
func (ps *ProxyTemplate) generateProxyConfig(proxies []*models.ProxyNode) string {
	var config strings.Builder
	for _, proxy := range proxies {
		config.WriteString(fmt.Sprintf("- { name: %s, type: anytls, server: %s, port: %d, password: %s, client-fingerprint: chrome, udp: true, idle-session-check-interval: 30, idle-session-timeout: 30, min-idle-session: 0, sni: \"example.com\", alpn: [h2, http/1.1], skip-cert-verify: true }\n",
			proxy.Name(), proxy.Host, proxy.Port, proxy.Password))
	}
	return config.String()
}

// generateProxyGroup 生成代理组配置
func (ps *ProxyTemplate) generateProxyGroup(proxies []*models.ProxyNode) string {
	var proxyNames []string
	for _, proxy := range proxies {
		proxyNames = append(proxyNames, proxy.Name())
	}

	group := fmt.Sprintf("- { name: PROXY, type: url-test, url: \"https://www.gstatic.com/generate_204\", interval: 300, proxies: [ \n%s ] }",
		strings.Join(proxyNames, ", "))

	return group
}

// generateRules 生成规则配置
func (ps *ProxyTemplate) generateRules() string {
	var rules strings.Builder
	for _, rule := range ps.rules {
		rules.WriteString(fmt.Sprintf("- %s,%s,%s\n", rule.Type, rule.Keyword, rule.Group))
	}
	rules.WriteString("- MATCH,PROXY\n")
	return rules.String()
}

// getTemplateHead 获取模板头部
func (ps *ProxyTemplate) getTemplateHead() string {
	return `mixed-port: 7890
allow-lan: true
bind-address: "*"
mode: rule
log-level: info
dns:
    enable: true
    ipv6: false
    default-nameserver: [223.5.5.5, 119.29.29.29]
    enhanced-mode: fake-ip
    fake-ip-range: 198.18.0.1/16
    use-hosts: true
    nameserver:
        ["https://doh.pub/dns-query", "https://dns.alidns.com/dns-query"]
    fallback:
        [
            "https://doh.dns.sb/dns-query",
            "https://dns.cloudflare.com/dns-query",
            "https://dns.twnic.tw/dns-query",
            "tls://8.8.4.4:853",
        ]
    fallback-filter: { geoip: true, ipcidr: [240.0.0.0/4, 0.0.0.0/32] }`
}

func (ps *ProxyTemplate) Consume() string {
	proxyConfigs := ps.generateProxyConfig(ps.proxies)
	proxyGroups := ps.generateProxyGroup(ps.proxies)
	rules := ps.generateRules()
	yamlConfig := ps.getTemplateHead() +
		"\nproxies:\n" + proxyConfigs +
		"\nproxy-groups:\n" + proxyGroups +
		"\nrules:\n" + rules
	return yamlConfig
}
